/**
 * authController.js - 身份验证控制器
 * 
 * 这个模块处理与身份验证相关的请求，如用户注册、登录、刷新令牌等。
 * 它使用userService来执行业务逻辑，并使用JWT进行身份验证。
 */

const jwt = require('jsonwebtoken');
const userService = require('../services/userService');
const { ApiError } = require('../utils/errors');
const { successResponse } = require('../utils/responseHandler');
const config = require('../config');
const logger = require('../utils/logger');

/**
 * 身份验证控制器类
 * 
 * 提供处理身份验证请求的方法
 */
class AuthController {
  /**
   * 注册新用户
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件函数
   */
  async register(req, res, next) {
    try {
      const { username, email, password } = req.body;

      // 创建用户
      const user = await userService.createUser({
        username,
        email,
        password,
      });

      // 生成令牌
      const token = jwt.sign(
        { id: user.id, role: user.role },
        config.jwt.secret,
        { expiresIn: config.jwt.accessExpiresIn }
      );

      // 生成刷新令牌
      const refreshToken = jwt.sign(
        { id: user.id },
        config.jwt.refreshSecret,
        { expiresIn: config.jwt.refreshExpiresIn }
      );

      // 保存刷新令牌
      await userService.updateRefreshToken(user.id, refreshToken);

      // 返回用户信息和令牌
      return successResponse(res, 201, '用户注册成功', {
        user,
        token,
        refreshToken,
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 用户登录
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件函数
   */
  async login(req, res, next) {
    try {
      const { email, password } = req.body;

      // 获取用户
      const user = await userService.getUserByEmail(email);

      // 验证密码
      const isPasswordValid = await user.validatePassword(password);
      if (!isPasswordValid) {
        throw new ApiError(401, '无效的凭据');
      }

      // 检查用户状态
      if (user.status !== 'active') {
        throw new ApiError(403, '账户已被禁用');
      }

      // 生成令牌
      const token = jwt.sign(
        { id: user.id, role: user.role },
        config.jwt.secret,
        { expiresIn: config.jwt.accessExpiresIn }
      );

      // 生成刷新令牌
      const refreshToken = jwt.sign(
        { id: user.id },
        config.jwt.refreshSecret,
        { expiresIn: config.jwt.refreshExpiresIn }
      );

      // 保存刷新令牌和更新最后登录时间
      await Promise.all([
        userService.updateRefreshToken(user.id, refreshToken),
        userService.updateLastLogin(user.id),
      ]);

      // 获取不包含密码的用户信息
      const userWithoutPassword = await userService.getUserById(user.id);

      // 返回用户信息和令牌
      return successResponse(res, 200, '登录成功', {
        user: userWithoutPassword,
        token,
        refreshToken,
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 刷新访问令牌
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件函数
   */
  async refreshToken(req, res, next) {
    try {
      const { refreshToken } = req.body;

      // 验证刷新令牌
      let decoded;
      try {
        decoded = jwt.verify(refreshToken, config.jwt.refreshSecret);
      } catch (error) {
        throw new ApiError(401, '无效或过期的刷新令牌');
      }

      // 获取用户
      const user = await userService.findUserByRefreshToken(refreshToken);

      // 生成新的访问令牌
      const token = jwt.sign(
        { id: user.id, role: user.role },
        config.jwt.secret,
        { expiresIn: config.jwt.accessExpiresIn }
      );

      // 生成新的刷新令牌
      const newRefreshToken = jwt.sign(
        { id: user.id },
        config.jwt.refreshSecret,
        { expiresIn: config.jwt.refreshExpiresIn }
      );

      // 更新刷新令牌
      await userService.updateRefreshToken(user.id, newRefreshToken);

      // 返回新的令牌
      return successResponse(res, 200, '令牌刷新成功', {
        token,
        refreshToken: newRefreshToken,
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 获取当前用户信息
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件函数
   */
  async getCurrentUser(req, res, next) {
    try {
      // 从请求对象中获取用户ID（由身份验证中间件设置）
      const userId = req.user.id;

      // 获取用户信息
      const user = await userService.getUserById(userId);

      // 返回用户信息
      return successResponse(res, 200, null, user);
    } catch (error) {
      next(error);
    }
  }

  /**
   * 用户登出
   * 
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件函数
   */
  async logout(req, res, next) {
    try {
      // 从请求对象中获取用户ID（由身份验证中间件设置）
      const userId = req.user.id;

      // 清除刷新令牌
      await userService.clearRefreshToken(userId);

      // 返回成功响应
      res.status(204).end();
    } catch (error) {
      next(error);
    }
  }
}

module.exports = new AuthController();